package data

import (
	"commerce/common"
	"commerce/model"
	"fmt"
	"strings"
)

func PageGoodsAttr(pageNo, pageSize int, name string) (*common.Page, error) {

	whereSql := composeGoodsAttrSearchQuerySql(name)

	row := common.DB.QueryRow("select count(*) FROM goods_attr a" + whereSql)
	var totalRecords int
	if err := row.Scan(&totalRecords); err != nil {
		return nil, err
	}
	stmt, err := common.DB.Prepare("select a.id, a.`name`, a.options, c.id as category_id, c.name as category_name FROM goods_attr a inner join category c on a.category_id = c.id " + whereSql + " LIMIT ?, ?")
	if err != nil {
		return nil, err
	}
	defer stmt.Close()

	rows, err := stmt.Query((pageNo-1)*pageSize, pageSize)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var gs []model.GoodsAttr
	for rows.Next() {
		g := model.GoodsAttr{}
		if err := rows.Scan(&g.Id, &g.Name, &g.Options, &g.CategoryId, &g.CategoryName); err != nil {
			return nil, fmt.Errorf("属性数据有误:%s", err.Error())
		}
		gs = append(gs, g)
	}
	return common.NewPage(gs, pageNo, pageSize, totalRecords), nil
}

func GetGoodsAttrById(id int) (*model.GoodsAttr, error) {

	sqlTpl := "select id, `name`, options, category_id FROM goods_attr where id = ?"

	stmt, err := common.DB.Prepare(sqlTpl)
	if err != nil {
		return nil, err
	}
	defer stmt.Close()

	var g model.GoodsAttr
	if err = stmt.QueryRow(id).Scan(&g.Id, &g.Name, &g.Options, &g.CategoryId); err != nil {
		return nil, err
	}
	return &g, nil
}

func ListGoodsAttrById(attrIds []int) ([]model.GoodsAttr, error) {

	sqlTpl := "select id, `name` FROM goods_attr where id in (?" + strings.Repeat(",?", len(attrIds)-1) + `)`

	stmt, err := common.DB.Prepare(sqlTpl)
	if err != nil {
		return nil, err
	}
	defer stmt.Close()

	args := make([]interface{}, len(attrIds))
	for i, id := range attrIds {
		args[i] = id
	}
	rows, err := stmt.Query(args...)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var gs []model.GoodsAttr
	for rows.Next() {
		g := model.GoodsAttr{}
		if err := rows.Scan(&g.Id, &g.Name); err != nil {
			return nil, fmt.Errorf("属性数据有误:%s", err.Error())
		}
		gs = append(gs, g)
	}
	return gs, nil
}

func ListAllGoodsAttr() ([]model.GoodsAttr, error) {

	sqlTpl := "select id, `name`, options FROM goods_attr where `enabled` = 1"
	stmt, err := common.DB.Prepare(sqlTpl)
	if err != nil {
		return nil, err
	}
	defer stmt.Close()

	rows, err := stmt.Query()
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var gs []model.GoodsAttr
	for rows.Next() {
		g := model.GoodsAttr{}
		if err := rows.Scan(&g.Id, &g.Name, &g.Options); err != nil {
			return nil, fmt.Errorf("属性数据有误:%s", err.Error())
		}
		gs = append(gs, g)
	}
	return gs, nil
}

func AddGoodsAttr(g model.GoodsAttr) (int, error) {

	sqlTpl := "insert into goods_attr(name, options, category_id) VALUES (?, ?, ?)"
	result, err := common.DB.Exec(sqlTpl, g.Name, g.Options, g.CategoryId)

	if err != nil {
		return 0, fmt.Errorf("save goods attr err: %v", err)
	}
	id, err := result.LastInsertId()

	if err != nil {
		return 0, fmt.Errorf("save goods attr insert id err: %v", err)
	}
	return int(id), nil
}

func UpdateGoodsAttr(g model.GoodsAttr) (int, error) {

	sqlTpl := "update goods_attr set `name`=?, options=?, category_id = ? WHERE id = ?"

	stmt, err := common.DB.Prepare(sqlTpl)
	if err != nil {
		return 0, err
	}
	defer stmt.Close()

	result, err := stmt.Exec(g.Name, g.Options, g.CategoryId, g.Id)
	if err != nil {
		return 0, fmt.Errorf("update good attr err:%v", err.Error())
	}
	rowsAffected, err := result.RowsAffected()
	return int(rowsAffected), err
}

func DeleteGoodsAttr(id int) error {

	sqlTpl := "delete from goods_attr WHERE id = ?"

	stmt, err := common.DB.Prepare(sqlTpl)
	if err != nil {
		return err
	}
	defer stmt.Close()

	_, err = stmt.Exec(id)
	if err != nil {
		return fmt.Errorf("delete good attr:id:%d, err:%v", id, err.Error())
	}
	return err
}

func composeInQuerySql(sql string, len int) string {

	// 没有条件查询
	if len == 0 {
		return sql
	}
	if len == 1 {
		return sql + " (?)"
	}
	sb := strings.Builder{}
	sb.WriteString(sql)
	sb.WriteString("(?, ")
	for i := 1; i < len; i++ {
		sb.WriteString(" ?")
	}
	sb.WriteString(")")
	return sb.String()
}

func composeGoodsAttrSearchQuerySql(name string) string {

	// 没有条件查询
	if len(name) == 0 {
		return ""
	}
	sb := strings.Builder{}
	sb.WriteString(" WHERE a.`name` like '" + strings.TrimSpace(name) + "%' ")

	return sb.String()
}
